#include "notewidget.h"
#include "ui_notewidget.h"

#include <QtGui>

NoteWidget::NoteWidget(QWidget *parent, QByteArray docHash, int id) :
	QFrame(parent),	ui(new Ui::NoteWidget), docHash(docHash), id(id)
{
	ui->setupUi(this);
	ui->labelMove->installEventFilter(this);
	ui->labelResize->installEventFilter(this);
	setMouseTracking(true);
	setHovered(false);
}

NoteWidget::~NoteWidget()
{
	delete ui;
}

int NoteWidget::getId()
{
	return id;
}

QVector<QColor> NoteWidget::getDefaultColors()
{
	QVector<QColor> result;
	result.append(QColor::fromHsv(120, 32, 255));
	result.append(QColor::fromHsv(60, 32, 255));
	result.append(QColor::fromHsv(0, 32, 255));
	result.append(QColor::fromHsv(180, 32, 255));
	result.append(QColor::fromHsv(240, 32, 255));
	result.append(QColor::fromHsv(300, 32, 255));
	return result;
}

QColor NoteWidget::getBgColor()
{
	return bgColor;
}

QString NoteWidget::getTitle()
{
	return ui->lineEdit->text();
}

void NoteWidget::setMaximized(bool value)
{
	ui->checkMaximize->setChecked(value);
	ui->widgetCenter->setVisible(value);
	ui->widgetBottom->setVisible(value);
	if (!value) {
		if (ui->lineEdit->text().isEmpty()) {
			ui->lineEdit->setVisible(false);
			setTransparency(false);
		} else {
			QFontMetrics fm(ui->lineEdit->font());
			ui->lineEdit->setMaximumWidth(fm.width(ui->lineEdit->text()) + 5);
			setTransparency(true);
		}
	} else {
		ui->lineEdit->setVisible(true);
		ui->lineEdit->setMaximumWidth(16777215);
		setTransparency(false);
	}
	myAdjustSize();
	emit maximizedChanged(docHash, id, value);
}

void NoteWidget::setPageNumber(int value)
{
	pageNumber = value;
}

int NoteWidget::getPageNumber()
{
	return pageNumber;
}

void NoteWidget::on_checkMaximize_toggled(bool checked)
{
	setMaximized(checked);
}

bool NoteWidget::eventFilter(QObject *obj, QEvent *event)
{
	if (obj == ui->labelMove) {
		if (event->type() == QEvent::MouseButtonPress) {
			QMouseEvent *e = dynamic_cast<QMouseEvent *>(event);
			if (e) {
				QPoint relPos = parentWidget()->mapFromGlobal(e->globalPos());
				mousePressPos = relPos;
				mousePressWidgetPos = this->pos();
			}
		} else if (event->type() == QEvent::MouseMove) {
			QMouseEvent *e = dynamic_cast<QMouseEvent *>(event);
			if (e) {
				if (e->buttons() & Qt::LeftButton) {
					QPoint relPos = parentWidget()->mapFromGlobal(e->globalPos());
					relPos.rx() = qMin(parentWidget()->width()-1, qMax(0, relPos.rx()));
					relPos.ry() = qMin(parentWidget()->height()-1, qMax(0, relPos.ry()));
					QPoint delta = relPos - mousePressPos;
					move(mousePressWidgetPos + delta);
					emit posChanged(docHash, id, pos());
				}
			}
		}
	} else if (obj == ui->labelResize) {
		if (event->type() == QEvent::MouseButtonPress) {
			QMouseEvent *e = dynamic_cast<QMouseEvent *>(event);
			if (e) {
				mousePressPos = parentWidget()->mapFromGlobal(e->globalPos());
				mousePressWidgetSize = size();
			}
		} else if (event->type() == QEvent::MouseMove) {
			QMouseEvent *e = dynamic_cast<QMouseEvent *>(event);
			if (e) {
				if (e->buttons() & Qt::LeftButton) {
					QPoint delta = parentWidget()->mapFromGlobal(e->globalPos()) - mousePressPos;
					QSize newSize = mousePressWidgetSize + QSize(delta.x(), delta.y());
					setMaximumSize(newSize);
					resize(newSize);
					emit maximumSizeChanged(docHash, id, maximumSize());
				}
			}
		}
	}

	bool result = QObject::eventFilter(obj, event);
	return result;
}

void NoteWidget::enterEvent(QEvent *)
{
	setHovered(true);
}

void NoteWidget::leaveEvent(QEvent *)
{
	setHovered(false);
}

void NoteWidget::myAdjustSize()
{
	if (ui->checkMaximize->isChecked()) {
		QSize szHint = sizeHint();
		QSize szMax = maximumSize();
		szHint.rwidth() = qMax(szHint.rwidth(), szMax.rwidth());
		szHint.rheight() = qMax(szHint.rheight(), szMax.rheight());
		setMaximumSize(szHint);
		resize(szHint);
		emit maximumSizeChanged(docHash, id, maximumSize());
	} else {
		adjustSize();
	}
}

void NoteWidget::setTransparency(bool transparent)
{
	if (transparent) {
		bgColor.setAlphaF(0.7);
	} else {
		bgColor.setAlphaF(1.0);
	}
	setBgColor(bgColor);
}

void NoteWidget::setBgColor(QColor color)
{
	bgColor = color;
	setStyleSheet(QString("QWidget {background:transparent} QToolButton:checked{background:rgba(128,128,128,64); border:0px;} NoteWidget{background: hsla(%1, %2, %3, %4)}").arg(bgColor.hue()).arg(bgColor.saturation()).arg(bgColor.value()).arg(bgColor.alpha()));
}

void NoteWidget::on_textEdit_textChanged()
{
	myAdjustSize();
	emit textChanged(docHash, id, ui->textEdit->toHtml());
}

void NoteWidget::on_btnDeleteNote_clicked()
{
	if (QMessageBox::question(0, "Delete note", "Are you sure you want to delete this note? The deletion is irreversible.", QMessageBox::Yes, QMessageBox::No)
			== QMessageBox::Yes) {
		emit deleteNoteRequested(docHash, id);
	}
}

void NoteWidget::setHovered(bool value)
{
	ui->stackedWidgetMaximize->setCurrentIndex(value ? 0 : 1);
	ui->stackedWidgetMove->setCurrentIndex(value ? 0 : 1);
	ui->stackedWidgetDelete->setCurrentIndex(value ? 0 : 1);
	ui->stackedWidgetFormatBar->setCurrentIndex(value ? 0 : 1);
	setTransparency(value ? false : (ui->checkMaximize->isChecked() ? false : (ui->lineEdit->text().isEmpty() ? false : true)));
}

void NoteWidget::on_btnPickBgColor_clicked()
{
	QColorDialog dialog;
	QColor c = bgColor;
	c.setAlphaF(1.0);
	dialog.setCurrentColor(c);
	QVector<QColor> defaultColors = getDefaultColors();
	for (int i = 0; i < defaultColors.count(); i++) {
		dialog.setCustomColor(i, defaultColors[i].rgb());
	}
	dialog.setWindowTitle("Select note background color");

	if (dialog.exec() != QDialog::Accepted)
		return;
	c = dialog.currentColor();
	c.setAlpha(bgColor.alpha());
	setBgColor(c);
	emit colorChanged(docHash, id, c);
}

void NoteWidget::on_lineEdit_textChanged(const QString &s)
{
	if (!ui->checkMaximize->isChecked()) {
		QFontMetrics fm(ui->lineEdit->font());
		ui->lineEdit->setMaximumWidth(fm.width(s) + 5);
		myAdjustSize();
	}
	emit titleChanged(docHash, id, ui->lineEdit->text());
}


void NoteWidget::setTitle(QString title)
{
	ui->lineEdit->setText(title);
}

void NoteWidget::setText(QString text)
{
	ui->textEdit->setText(text);
}

void NoteWidget::setColor(QColor color)
{
	setBgColor(color);
}

void NoteWidget::setPos(QPointF normPos)
{
	this->normPos = normPos;
}

QPointF NoteWidget::getPos()
{
	return normPos;
}

void NoteWidget::on_btnBold_toggled(bool checked)
{
	ui->textEdit->setFontWeight(checked ? QFont::Bold : QFont::Normal);
	ui->textEdit->setFocus();
}

void NoteWidget::on_textEdit_currentFontChanged(const QFont &f)
{
	if (ui->textEdit->textCursor().anchor() != ui->textEdit->textCursor().position()) {
		// something is selected, do not touch the buttons or we alter the format
		return;
	}
	ui->btnBold->setChecked(f.weight() == QFont::Bold);
	ui->btnItalic->setChecked(f.style() == QFont::StyleItalic);
	ui->btnUnderline->setChecked(ui->textEdit->currentCharFormat().fontUnderline());
	ui->btnStrikethrough->setChecked(ui->textEdit->currentCharFormat().fontStrikeOut());
	ui->btnMonospace->setChecked(ui->textEdit->currentCharFormat().fontStyleHint() == QFont::Courier);
	ui->btnSubscript->setChecked(ui->textEdit->currentCharFormat().verticalAlignment() == QTextCharFormat::AlignSubScript);
	ui->btnSuperscript->setChecked(ui->textEdit->currentCharFormat().verticalAlignment() == QTextCharFormat::AlignSuperScript);
}

void NoteWidget::on_btnItalic_toggled(bool checked)
{
	ui->textEdit->setFontItalic(checked);
	ui->textEdit->setFocus();
}

void NoteWidget::on_btnUnderline_toggled(bool checked)
{
	ui->textEdit->setFontUnderline(checked);
	ui->textEdit->setFocus();
}

void NoteWidget::on_btnStrikethrough_toggled(bool checked)
{
	QTextCharFormat f = ui->textEdit->currentCharFormat();
	f.setFontStrikeOut(checked);
	ui->textEdit->setCurrentCharFormat(f);
	ui->textEdit->setFocus();
}

void NoteWidget::on_btnMonospace_toggled(bool checked)
{
	QTextCharFormat f = ui->textEdit->currentCharFormat();
	f.setFontStyleHint(checked ? QFont::Courier : QFont::Helvetica);
	ui->textEdit->setCurrentCharFormat(f);
	ui->textEdit->setFocus();
}

void NoteWidget::on_btnSubscript_toggled(bool )
{
	QTextCharFormat f = ui->textEdit->currentCharFormat();
	if (ui->btnSubscript->isChecked()) {
		f.setVerticalAlignment(QTextCharFormat::AlignSubScript);
		ui->btnSuperscript->setChecked(false);
	} else if (ui->btnSuperscript->isChecked()) {
		f.setVerticalAlignment(QTextCharFormat::AlignSuperScript);
		ui->btnSubscript->setChecked(false);
	} else {
		f.setVerticalAlignment(QTextCharFormat::AlignNormal);
	}
	ui->textEdit->setCurrentCharFormat(f);
	ui->textEdit->setFocus();
}

void NoteWidget::on_btnSuperscript_toggled(bool )
{
	QTextCharFormat f = ui->textEdit->currentCharFormat();
	if (ui->btnSuperscript->isChecked()) {
		f.setVerticalAlignment(QTextCharFormat::AlignSuperScript);
		ui->btnSubscript->setChecked(false);
	} else if (ui->btnSubscript->isChecked()) {
		f.setVerticalAlignment(QTextCharFormat::AlignSubScript);
		ui->btnSuperscript->setChecked(false);
	} else {
		f.setVerticalAlignment(QTextCharFormat::AlignNormal);
	}
	ui->textEdit->setCurrentCharFormat(f);
	ui->textEdit->setFocus();
}

void NoteWidget::on_btnPickTextColor_clicked()
{
	QColorDialog dialog;
	dialog.setCurrentColor(ui->textEdit->textColor());
	dialog.setWindowTitle("Select text color");

	if (dialog.exec() != QDialog::Accepted)
		return;
	ui->textEdit->setTextColor(dialog.currentColor());
	ui->textEdit->setFocus();
}
